package com.example.demo.day0304;

public class DemoThread2 {
    public static void main(String[] args) {
        Acount a = new Acount();//定义Acount对象
        Acount a1= new Acount();
        //定义多线程对象
        User u_wexin = new User(a,2000);
        User u_zhifubao = new User(a,2000);
//        User u_wexin = new User(a,2000);
//        User u_zhifubao = new User(a1,2000);
        Thread weixin = new Thread(u_wexin,"微信");
        Thread zhifubao = new Thread(u_zhifubao,"支付宝");

        weixin.start();
        zhifubao.start();

    }
}
class  Acount{//多线程调用这个方法，就有问题，线程共享资源时，一个线程在执行这个方法没有完毕时，其他线程也开始执行这个方法，导致钱变为负数
    //需要先让一个线程整体执行完这个方法，另一个线程在执行，可以通过synchronized关键字
    public static int money = 3000;
    public synchronized void drawing(int m){//加上同步锁，锁的是对象a，不是方法drawing,不同的对象需要不同的锁
        String name = Thread.currentThread().getName();
        if (money < m){
            System.out.println(name + "账户余额不足");
        }else {
            System.out.println(name + "操作，账户原有金额：" + money);
            System.out.println(name + "操作，取款机额：" + m);

            money = money - m;
            System.out.println(name + "余额" + money);

        }
    }
    public synchronized void drawing1(int m){
        String name = Thread.currentThread().getName();
        if (money < m){
            System.out.println(name + "账户余额不足");
        }else {
            System.out.println(name + "操作，账户原有金额：" + money);
            System.out.println(name + "操作，取款机额：" + m);

            money = money - m;
            System.out.println(name + "余额" + money);

        }
    }
    public static synchronized void drawing2(int m){//静态的方法用synchronized修饰，两个对象可以使用同一个锁
        String name = Thread.currentThread().getName();
        if (money < m){
            System.out.println(name + "账户余额不足");
        }else {
            System.out.println(name + "操作，账户原有金额：" + money);
            System.out.println(name + "操作，取款机额：" + m);

            money = money - m;
            System.out.println(name + "余额" + money);

        }
    }
    public void drawing3(int m){
        synchronized (this){//当前代码块加同步锁
            //用this锁代码，不论几个对象都是使用的一个同步锁
            String name = Thread.currentThread().getName();
            if (money < m){
                System.out.println(name + "账户余额不足");
            }else {
                System.out.println(name + "操作，账户原有金额：" + money);
                System.out.println(name + "操作，取款机额：" + m);

                money = money - m;
                System.out.println(name + "余额" + money);
            }
        }
    }

    /**
     * @todo synchronized后加类或者引用对象的区别
     * @param m
     * @param a
     */
    public void drawing4(int m,Acount a){
        synchronized (a){//当前代码块加同步锁
            //表示类Acount的对象a的同步锁,但是a1没有加同步锁
            String name = Thread.currentThread().getName();
            if (money < m){
                System.out.println(name + "账户余额不足");
            }else {
                System.out.println(name + "操作，账户原有金额：" + money);
                System.out.println(name + "操作，取款机额：" + m);

                money = money - m;
                System.out.println(name + "余额" + money);
            }
        }
    }
    public void drawing5(int m,Acount a){
        synchronized (a){//当前代码块加同步锁
            //表示类Acount的对象a的同步锁
            String name = Thread.currentThread().getName();
            if (name.equals("微信")){
                try {
                    a.wait();//当前线程进入等待的阻塞状态
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (money < m){
                System.out.println(name + "账户余额不足");
            }else {
                System.out.println(name + "操作，账户原有金额：" + money);
                System.out.println(name + "操作，取款机额：" + m);

                money = money - m;
                System.out.println(name + "余额" + money);
            }
            if (name.equals("支付宝")){
                a.notify();//唤醒当前优先级最高的线程进入就绪状态
                //wait(),notify(),notifyAll()这三个方法只能用再有同步锁的方法或者代码块中
            }
        }
    }
    public void drawing6(int m){
        synchronized (Acount){//当前代码块加同步锁
            //用this锁代码，不论几个对象都是使用的一个同步锁
            String name = Thread.currentThread().getName();
            if (money < m){
                System.out.println(name + "账户余额不足");
            }else {
                System.out.println(name + "操作，账户原有金额：" + money);
                System.out.println(name + "操作，取款机额：" + m);

                money = money - m;
                System.out.println(name + "余额" + money);
            }
        }
    }
}
class User implements Runnable{
    Acount acount;
    int money;
    public User (Acount acount,int money){
        this.acount = acount;
        this.money = money;
    }
    public void run() {
//        acount.drawing(money);
//        if (Thread.currentThread().getName().equals("微信")){
//            acount.drawing(money);
//        }else{
//            acount.drawing1(money);
//        }
//        acount.drawing2(money);//调用类的静态方法
//        acount.drawing3(money);
//        acount.drawing4(money,acount);
        acount.drawing5(money,acount);
    }
}